﻿/**
 * Create in 2012-4-3.
 */
package kit4j.view.cs.swing.window;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.GridLayout;
import java.awt.Window;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingConstants;

import kit4j.common.task.ProgressionalTask;
import kit4j.common.task.Task;
import kit4j.common.task.event.TaskProgressRateChangeEvent;
import kit4j.common.task.event.TaskProgressRateChangeListener;
import kit4j.common.task.event.TaskStateChangeEvent;
import kit4j.common.task.event.TaskStateChangeListener;
import kit4j.common.task.executor.SequentialTaskExecutor;
import kit4j.common.task.executor.TaskExecutor;
import kit4j.view.cs.component.FullComponent;
import kit4j.view.cs.swing.component.JFullLabel;
import kit4j.view.cs.swing.panel.JFullPanel;

/**
 * 启动窗口。
 * 
 * @author MiniKnife
 * 
 */
public class StartWindow extends JFullWindow implements FullComponent, Runnable {

	private static final long serialVersionUID = 1L;

	private JFullPanel taskDescriptionLabelPane;

	private JLabel taskDescriptionLabel;

	private JProgressBar progressBar;

	private List<ProgressionalTask> taskList;

	public StartWindow() {
		super();

		init();
	}

	/**
	 * @param owner
	 */
	public StartWindow(Frame owner) {
		super(owner);

		init();
	}

	/**
	 * @param gc
	 */
	public StartWindow(GraphicsConfiguration gc) {
		super(gc);

		init();
	}

	/**
	 * @param owner
	 * @param gc
	 */
	public StartWindow(Window owner, GraphicsConfiguration gc) {
		super(owner, gc);

		init();
	}

	/**
	 * @param owner
	 */
	public StartWindow(Window owner) {
		super(owner);

		init();
	}

	/**
	 * 初始化该启动窗口。
	 */
	private void init() {
		initWindow();
		initFields();
	}

	private void initWindow() {
		setAutoGenerateComponentsBackgroundImage(true);
	}

	private void initFields() {
		taskList = new ArrayList<ProgressionalTask>();
	}

	public void addTask(ProgressionalTask task) {
		taskList.add(task);
	}

	public void run() {
		setVisible(true);

		beforeStart();
		start();
		afterStart();
	}

	protected void beforeStart() {

	}

	protected void start() {
		initComponents();

		startTasks();
	}

	private void initComponents() {
		iniTaskDescriptionLabelPane();
		initTaskDescriptionLabel();
		initProgressBar();
		initTaskListener();
		initComponentsLayout();
	}

	private void iniTaskDescriptionLabelPane() {
		if(taskDescriptionLabelPane == null) {
			taskDescriptionLabelPane = new JFullPanel();
		}
	}

	private void initTaskDescriptionLabel() {
		if(taskDescriptionLabel == null) {
			taskDescriptionLabel = new JFullLabel();
			taskDescriptionLabel.setForeground(Color.GRAY);
			taskDescriptionLabel.setFont(new Font(Font.SERIF, Font.PLAIN, 12));
		}
	}

	private void initProgressBar() {
		if(progressBar == null) {
			progressBar = new JProgressBar(SwingConstants.HORIZONTAL);
			progressBar.setMaximum(getTasksLength());
		}
	}

	private int getTasksLength() {
		int length = 0;

		for (ProgressionalTask t : taskList) {
			length += t.getTaskLength();
		}

		return length;
	}

	private void initTaskListener() {
		TaskStateChangeListener stateChangeListener = createTaskStateChangeListener();
		TaskProgressRateChangeListener progressRateChangeListener = createTaskProgressRateChangeListener();

		for (ProgressionalTask t : taskList) {
			t.addTaskStateChangeListener(stateChangeListener);
			t.addTaskProgressRateChangeListener(progressRateChangeListener);
		}
	}

	private TaskStateChangeListener createTaskStateChangeListener() {
		return new TaskStateChangeListener() {

			@Override
			public void taskStateChanged(TaskStateChangeEvent evt) {
				Task task = evt.getTask();
				taskDescriptionLabel.setText(task.getDescription());
			}
		};
	}

	private TaskProgressRateChangeListener createTaskProgressRateChangeListener() {
		return new TaskProgressRateChangeListener() {

			@Override
			public void taskProgressRateChanged(TaskProgressRateChangeEvent evt) {
				long oldProgressRate = evt.getOldTaskProgressRate();
				long currentProgressRate = evt.getCurrentTaskProgressRate();
				long totalProgressRate = progressBar.getValue();

				progressBar.setValue((int) (totalProgressRate + currentProgressRate - oldProgressRate));
			}
		};
	}

	private void initComponentsLayout() {
		taskDescriptionLabel.setBounds(8, 215, getWidth(), 30);

		taskDescriptionLabelPane.setLayout(null);
		taskDescriptionLabelPane.add(taskDescriptionLabel);

		JFullPanel progressBarPane = new JFullPanel();
		progressBarPane.setLayout(new GridLayout(1, 1));
		progressBarPane.add(progressBar);

		setLayout(new BorderLayout());
		add(taskDescriptionLabelPane, BorderLayout.CENTER);
		add(progressBarPane, BorderLayout.SOUTH);

		validate();
	}

	private void startTasks() {
		TaskExecutor taskExecutor = new SequentialTaskExecutor();

		for (Task t : taskList) {
			taskExecutor.addTask(t);
		}

		taskExecutor.start();
		taskExecutor.waitForAllTasksComplete();
	}

	protected void afterStart() {

	}

}
